//---------------------------------------------------------------------
// File: SendPortConductorStep.cs
// 
// Summary: 
//---------------------------------------------------------------------

using System;
using System.Threading;
using System.Xml;
using Microsoft.BizTalk.ExplorerOM;
using Microsoft.Services.BizTalkApplicationFramework.BizUnit;

namespace BizUnit.Extensions.BizTalk
{
    /// <summary>
    /// The ApplicationConductorStep starts/stops a Application.
	/// </summary>

	/// <remarks>
	/// The following shows an example of the Xml representation of this test step.
	/// 
	/// <code escaped="true">
    /// <TestStep assemblyPath="BizUnitExtensions.BizTalk.dll" typeName="BizUnit.Extensions.BizTalk.ApplicationConductorStep">
	///		<DelayForCompletion>5</DelayForCompletion> <!-- Optional, seconds to delay for this step to complete -->
    ///		<ApplicationName></ApplicationName>
    ///		<ConnectionString></ConnectionString>
	///		<Action>Start|Stop</Action>
	/// </TestStep>
	/// </code>
	///	
	///	<list type="table">
	///		<listheader>
	///			<term>Tag</term>
	///			<description>Description</description>
	///		</listheader>
	///		<item>
	///			<term>DelayForCompletion</term>
	///			<description>The number of seconds to deplay for this step to complete</description>
	///		</item>
	///		<item>
	///			<term>ApplicationName</term>
	///			<description>The name of the Application to containing the Application to start/stop</description>
	///		</item>
    /// 	<item>
    ///			<term>ConnectionString</term>
    ///			<description>The connectionstring to the management database</description>
    ///		</item>
	///		<item>
	///			<term>Action</term>
	///			<description>Start|Stop</description>
	///		</item>
	///	</list>
	///	</remarks>

    public class ApplicationConductorStep : ITestStep
	{
		public enum ApplicationAction 
		{
			Start,
			Stop,
		}

		#region ITestStep Members

		/// <summary>
		/// ITestStep.Execute() implementation
		/// </summary>
		/// <param name='testConfig'>The Xml fragment containing the configuration for this test step</param>
		/// <param name='context'>The context for the test, this holds state that is passed beteen tests</param>
		public void Execute(XmlNode testConfig, Context context)
		{
			string applicationName = context.ReadConfigAsString(testConfig, "ApplicationName");
            string connectionString = context.ReadConfigAsString(testConfig, "ConnectionString");
            //string applicationOption = context.ReadConfigAsString(testConfig, "ApplicationOption");
            ApplicationAction action = (ApplicationAction)Enum.Parse(typeof(ApplicationAction), context.ReadConfigAsString(testConfig, "Action"), true);
		    
            if (action == ApplicationAction.Start)
			{
                Start(applicationName, context, connectionString);
			}
			else
			{
                Stop(applicationName, context, connectionString);
			}

			// Delay if necessary to allow the orchestration to start/stop
			int delayForCompletion = context.ReadConfigAsInt32(testConfig, "DelayForCompletion", true);
			if (delayForCompletion > 0)
			{
				context.LogInfo("Waiting for {0} seconds before recommencing testing.", delayForCompletion);
				Thread.Sleep(delayForCompletion*1000);
			}
		}

		#endregion

		private void Start( string applicationName, Context context, string connectionString )
		{
            BtsCatalogExplorer root = new BtsCatalogExplorer();
            root.ConnectionString = connectionString;
            foreach (Application application in root.Applications)
            {
                if(application.Name == applicationName)
                {
                    context.LogInfo("Starting Application {0} ", applicationName);
                    application.Start(ApplicationStartOption.StartAll);
                    root.SaveChanges();
                }
            }
		}

		private void Stop( string applicationName, Context context, string connectionString )
		{
            BtsCatalogExplorer root = new BtsCatalogExplorer();
            root.ConnectionString = connectionString;
            foreach (Application application in root.Applications)
            {
                if (application.Name == applicationName)
                {
                    context.LogInfo("Stopping Application {0} ", applicationName);
                    application.Stop(ApplicationStopOption.StopAll);
                    root.SaveChanges();
                }
            }																													
		}
	}
}
